#include "sfile.h"

extern "C" {
#include <hdf/mfhdf.h>
}

namespace sds {
  
  SFile::SFile(const std::string& filename, OpenMode mode) {
    switch (mode) {
    case READ:
      fileId = SDstart(filename.c_str(), DFACC_READ);
      SDfileinfo(fileId, &dataset, &attribute);
      break;
    case WRITE:
      fileId = SDstart(filename.c_str(), DFACC_WRITE);
      SDfileinfo(fileId, &dataset, &attribute);
      break;
    case CREATE:
      fileId = SDstart(filename.c_str(), DFACC_CREATE);
      dataset = attribute = 0;
      break;      
    }
    assert(fileId != FAIL);
  }

  SFile::SFile(const char* filename, OpenMode mode) {
    switch (mode) {
    case READ:
      fileId = SDstart(filename, DFACC_READ);
      SDfileinfo(fileId, &dataset, &attribute);
      break;
    case WRITE:
      fileId = SDstart(filename, DFACC_WRITE);
      SDfileinfo(fileId, &dataset, &attribute);
      break;
    case CREATE:
      fileId = SDstart(filename, DFACC_CREATE);
      dataset = attribute = 0;
      break;      
    }
    assert(fileId != FAIL);
  }

  
  SFile::~SFile() {
    SDend(fileId);
  }

  SDataset SFile::getDataset(const std::string& name) const {
    SInteger index = SDnametoindex(fileId, name.c_str());
    assert( index != FAIL);
    return getDataset(index);
  }

  SDataset SFile::createDataset(const std::string& name, SDataType type,
				const std::vector<SInteger>& size) {
    SInteger sizeTmp[MAX_VAR_DIMS];
    assert(size.size() <= MAX_VAR_DIMS);
    std::copy(size.begin(), size.end(), sizeTmp);
    SInteger typeTmp = SDataTypeConverter::inverse(type);
    assert(typeTmp != FAIL);
    SInteger index = SDcreate(fileId, name.c_str(), typeTmp, size.size(), sizeTmp);
    assert(index != FAIL);
    ++dataset;
    return SDataset(fileId, dataset - 1);
  }

  SAttribute SFile::getAttribute(const std::string& name) const {
    SInteger index = SDfindattr(fileId, name.c_str());
    assert( index != FAIL);
    return getAttribute(index);
  }


}
